package cn.monkey.family.rbac.dsl.http.jakarta;

import cn.monkey.family.rbac.dsl.http.HttpRequestPredicate;
import cn.monkey.family.rbac.dsl.http.HttpRequestPredicateDefinition;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Setter;
import org.springframework.util.AntPathMatcher;

import java.util.Arrays;
import java.util.Optional;

@Setter
public class DefaultJakartaHttpServletRequestPredicateFactory implements JakartaHttpServletRequestPredicateFactory {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public HttpRequestPredicate<HttpServletRequest> create(HttpRequestPredicateDefinition httpRequestPredicateDefinition) {
        HttpRequestPredicate<HttpServletRequest> p = new DefaultHttpServletRequestPredicate(httpRequestPredicateDefinition, this.antPathMatcher);
        HttpRequestPredicateDefinition[] and = httpRequestPredicateDefinition.getAnd();
        if (and != null) {
            Optional<HttpRequestPredicate<HttpServletRequest>> reduce = Arrays.stream(and)
                    .map(pd -> (HttpRequestPredicate<HttpServletRequest>) new DefaultHttpServletRequestPredicate(pd, this.antPathMatcher))
                    .reduce(HttpRequestPredicate::and);
            p = reduce.map(p::and).orElse(p);
        }
        HttpRequestPredicateDefinition[] or = httpRequestPredicateDefinition.getOr();
        if (or != null) {
            Optional<HttpRequestPredicate<HttpServletRequest>> reduce = Arrays.stream(or)
                    .map(pd -> (HttpRequestPredicate<HttpServletRequest>) new DefaultHttpServletRequestPredicate(pd, this.antPathMatcher))
                    .reduce(HttpRequestPredicate::or);
            p = reduce.map(p::or).orElse(p);
        }
        return p;
    }
}
